
// 1. 判断机器字节序
//  #include <iostream>

// union
// {
//     short data;
//     char bytes[sizeof(short)];
// }endian;

// int main()
// {
//     endian.data = 0x0102;
//     // 高权值位在低地址处&&低权值位在高地址处
//     if(endian.bytes[0] == 1 && endian.bytes[1] == 2)
//     {
//         std::cout << "大端" << std::endl;
//     }
//     else if(endian.bytes[0] == 2 && endian.bytes[1] == 1)
//     {
//         std::cout << "小端" << std::endl;
//     }
//     return 0;
// }

// 2. 主机字节序和网络字节序互相转换
//  #include <arpa/inet.h>
//  #include <sys/socket.h>
//  #include <netinet/in.h>
//  #include <iostream>

// int main()
// {
//     uint32_t ret1 = htonl(100);
//     std::cout << ret1 << std::endl;
//     ret1 = ntohl(ret1);
//     std::cout << ret1 << std::endl;
//     uint32_t ret2 = htons(20);
//     std::cout << ret2 << std::endl;
//     ret2 = ntohs(ret2);
//     std::cout << ret2 << std::endl;

//     // in_addr_t ret3 = inet_addr("1.1.1.1");// 将字符串转换为网络字节序的整数
//     // std::cout << ret3 << std::endl;
//     // struct in_addr ia;
//     // ia.s_addr = ret3;
//     // char *ipstr = inet_ntoa(ia);// 将网络字节序的整数转换为字符串
//     // std::cout << ipstr << std::endl;

//     struct in_addr ia;
//     inet_aton("1.1.1.1",&ia);
//     std::cout << ia.s_addr << std::endl;
//     char *ipstr = inet_ntoa(ia);

//     struct in_addr ia2;
//     inet_aton("2.2.2.2",&ia2);
//     std::cout << ia2.s_addr << std::endl;
//     char *ipstr2 = inet_ntoa(ia2);
//     // inet_ntoa的返回值指向的是静态区的内容，所以它很容易被最后一次调用覆盖
//     std::cout << ipstr << std::endl;
//     std::cout << ipstr2 << std::endl;

//     struct in_addr ia3;
//     inet_pton(AF_INET,"2.2.2.2",&ia3);
//     std::cout << ia3.s_addr << std::endl;
//     char buffer[32] = {0};
//     inet_ntop(AF_INET,&ia3,buffer,sizeof(buffer));
//     std::cout << buffer << std::endl;
//     return 0;
// }

// 3. socket API
//  #include <arpa/inet.h>
//  #include <sys/socket.h>
//  #include <netinet/in.h>
//  #include <unistd.h>

// #include <iostream>

// int main()
// {
//     // SOCK_CLOEXEC:子进程执行exec后能将继承自父进程的socket文件关闭
//     int fd = socket(AF_INET,SOCK_STREAM | SOCK_CLOEXEC,0);
//     pid_t n = fork();
//     if(n == 0)
//     {
//         execl("./a.out",nullptr);
//     }
//     std::cout << fd << std::endl;
//     while(true);
//     close(fd);
//     return 0;
// }

// 4. 测试backlog
//  #include <arpa/inet.h>
//  #include <sys/socket.h>
//  #include <netinet/in.h>
//  #include <unistd.h>
//  #include <string.h>

// #include <iostream>

// int main()
// {
//     int fd = socket(AF_INET,SOCK_STREAM,0);
//     struct sockaddr_in ipv4;
//     memset(&ipv4,0,sizeof(ipv4));
//     ipv4.sin_family = AF_INET;
//     ipv4.sin_port = htons(9090);
//     ipv4.sin_addr.s_addr = inet_addr("0.0.0.0");
//     socklen_t len = sizeof(ipv4);
//     bind(fd,(const sockaddr *)&ipv4,len);
//     listen(fd,2);
//     while(true);
//     return 0;
// }

// 5. 测试accept
//  #include <arpa/inet.h>
//  #include <sys/socket.h>
//  #include <netinet/in.h>
//  #include <unistd.h>
//  #include <string.h>

// #include <iostream>

// int main()
// {
//     int fd = socket(AF_INET,SOCK_STREAM,0);
//     struct sockaddr_in ipv4;
//     memset(&ipv4,0,sizeof(ipv4));
//     ipv4.sin_family = AF_INET;
//     ipv4.sin_port = htons(9090);
//     ipv4.sin_addr.s_addr = inet_addr("0.0.0.0");
//     socklen_t len = sizeof(ipv4);
//     bind(fd,(const sockaddr *)&ipv4,len);
//     listen(fd,2);

//     sleep(20);
//     struct sockaddr_in client;
//     len = sizeof(client);
//     int n = accept(fd,(sockaddr *)&client,&len);
//     if(n < 0)
//     {
//         std::cout << "accept失败！" << std::endl;
//     }
//     else
//     {
//         std::cout << inet_ntoa(client.sin_addr) << std::endl;
//         std::cout << ntohs(client.sin_port) << std::endl;
//     }
//     while(true);
//     return 0;
// }

// 6. 测试读写接口、带外数据
// #include <arpa/inet.h>
// #include <sys/socket.h>
// #include <sys/types.h>
// #include <netinet/in.h>
// #include <unistd.h>
// #include <string.h>
// #include <signal.h>
// #include <iostream>
// #include <functional>

// bool urg = false;
// void handle_urg(int sid)
// {
//     urg = true;
// }

// // server
// int main()
// {
//     // 0. 带外数据信号重定向
//     // 1. 创建套接字
//     int listenfd = socket(AF_INET, SOCK_STREAM, 0);
//     int val = 1;
//     setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val));
//     // 2. 绑定套接字
//     struct sockaddr_in server;
//     memset(&server, 0, sizeof(server));
//     socklen_t len = sizeof(server);
//     server.sin_family = AF_INET;
//     server.sin_port = htons(9090);
//     server.sin_addr.s_addr = inet_addr("0.0.0.0");
//     int n = bind(listenfd, (const struct sockaddr *)&server, len);
//     if(n == -1)
//     {
//         std::cout << "绑定失败！" << std::endl;
//         return -1;
//     }
//     // 3. 开始监听
//     listen(listenfd, 5);
//     // 4. 获取连接
//     struct sockaddr_in client;
//     socklen_t len_client = sizeof(client);
//     int sockfd = accept(listenfd, (struct sockaddr *)&client, &len_client);
//     // signal(SIGURG, handle_urg);
//     //  5. 读写数据
//     int cnt = 20;
//     while (cnt--)
//     {
//         if (sockatmark(sockfd))
//         {
//             char ch;
//             recv(sockfd, &ch, 1, MSG_OOB);
//             std::cout << "接收到带外数据:" << ch << std::endl;
//         }
//         char ch;
//         char buffer[1024] = {0};
//         int n = recv(sockfd, buffer, sizeof(buffer) - 1, 0);
//         if (n > 0)
//         {
//             buffer[n] = 0;
//             std::cout << buffer << std::endl;
//         }
//         sleep(1);
//     }
//     close(sockfd);
//     return 0;
// }


//7. 网络信息API测试
// #include <arpa/inet.h>
// #include <sys/socket.h>
// #include <sys/types.h>
// #include <netinet/in.h>
// #include <unistd.h>
// #include <stdio.h>
// #include <string.h>
// #include <signal.h>
// #include <iostream>
// #include <netdb.h>


// int main()
// {
//     struct sockaddr_in server;
//     server.sin_addr.s_addr = inet_addr("127.27.236.117");

//     struct hostent *ret = gethostbyaddr((void *)&server.sin_addr,4,AF_INET);
//     if(ret == NULL)
//     {
//         std::cout << "错误！返回值为空！" << std::endl;
//         return -1;
//     }
//     std::cout << ret->h_name << std::endl;
//     return 0;
// }





 